package com.example.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.exception.GuliException;
import com.example.common.vo.CourseInfoVO;
import com.example.eduservice.entity.EduChapter;
import com.example.eduservice.entity.EduCourse;
import com.example.eduservice.entity.EduCourseDescription;
import com.example.eduservice.entity.frontvo.CourseDetailInfoVO;
import com.example.eduservice.entity.frontvo.CourseFrontIndexVO;
import com.example.eduservice.entity.vo.CoursePublishVO;
import com.example.eduservice.entity.vo.EduCourseInfoVO;
import com.example.eduservice.entity.vo.EduCourseQuery;
import com.example.eduservice.mapper.EduCourseDescriptionMapper;
import com.example.eduservice.mapper.EduCourseMapper;
import com.example.eduservice.service.EduChapterService;
import com.example.eduservice.service.EduCourseService;
import com.example.eduservice.service.EduVideoService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:tjf
 * @Description:
 */
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService{
    @Resource
    private EduCourseMapper courseMapper;
    @Resource
    private EduCourseDescriptionMapper descriptionMapper;
    @Resource
    private EduVideoService videoService;
    @Resource
    private EduChapterService chapterService;
    /**
     * 添加课程
     * @param courseVO
     */
    //todo_tjf (tjf,2024/2/6,Com_T) 把pid等字段改为not null
    @Transactional
    @Override
    public String saveEduCourse(EduCourseInfoVO courseVO) {
        String cid = "";
        if (courseVO != null){
            EduCourse course = new EduCourse();
            // 属性赋值
            BeanUtils.copyProperties(courseVO, course);
            // 保存课程信息
            int insert = courseMapper.insert(course);
            if (insert <= 0){
                throw new GuliException(20001, "添加课程失败");
            }

            // 保存课程简介
            cid = course.getId();
            EduCourseDescription courseDescription = new EduCourseDescription();
            // 课程简介主键id和课程主键id保持一致
            courseDescription.setId(cid);
            courseDescription.setDescription(courseVO.getDescription());
            insert = descriptionMapper.insert(courseDescription);
            if (insert <= 0){
                throw new GuliException(20001, "添加课程失败");
            }
        }

        return cid;
    }

    /**
     * 根据id查询课程信息
     * @param courseId
     * @return
     */
    @Override
    public EduCourseInfoVO queryCourseInfoById(String courseId) {
        // 1 查询课程的信息
        EduCourse course = courseMapper.selectById(courseId);

        // 2 查询课程的简介
        EduCourseDescription courseDescription = descriptionMapper.selectById(courseId);

        // 3 把1和2的结果封装到EduCourseInfoVO对象中
        EduCourseInfoVO courseInfoVO = new EduCourseInfoVO();
        BeanUtils.copyProperties(course, courseInfoVO);
        courseInfoVO.setDescription(courseDescription.getDescription());

        return courseInfoVO;
    }

    /**
     * 修改课程信息
     * @param courseInfoVO
     */
    @Transactional
    @Override
    public void modifyCourseInfo(EduCourseInfoVO courseInfoVO) {
        // 1 修改课程信息
        EduCourse course = new EduCourse();
        BeanUtils.copyProperties(courseInfoVO, course);
        int update = courseMapper.updateById(course);

        if (update <= 0){
            throw new GuliException(20001, "修改课程信息失败！");
        }
        // 2 修改课程简介
        EduCourseDescription courseDescription = new EduCourseDescription();
        BeanUtils.copyProperties(courseInfoVO, courseDescription);
        update = descriptionMapper.updateById(courseDescription);

        if (update <= 0){
            throw new GuliException(20001, "修改课程简介失败！");
        }
    }

    /**
     * 根据id，查询课程发布信息
     * @param courseId
     * @return
     */
    @Override
    public CoursePublishVO queryCoursePublishInfoById(String courseId) {
        if (StringUtils.isNotBlank(courseId)){
            CoursePublishVO publishVO = courseMapper.selectCoursePublishVOByCourseId(courseId);
            return publishVO;
        }
        throw new GuliException(20001, "课程id不能为空");
    }

    /**
     * 根据课程id，确认发布课程
     * @param courseId
     */
    @Override
    public void publishCourse(String courseId) {
        EduCourse course = new EduCourse();
        course.setId(courseId);
        course.setStatus("Normal");
        courseMapper.updateById(course);
    }

    /**
     * 条件查询课程列表带分页
     * @param begin
     * @param limit
     * @param courseQuery
     * @return
     */
    @Override
    public Page<EduCourse> queryCourseListByConditionForPage(Integer begin, Integer limit, EduCourseQuery courseQuery) {
        // 设置默认值
        if (begin == null || begin < 1){
            begin = 1;
        }
        if (limit == null || limit <= 0){
            limit = 5;
        }
        Page<EduCourse> page = new Page<>();
        page.setCurrent(begin);
        page.setSize(limit);

        String title = courseQuery.getTitle();
        String status = courseQuery.getStatus();

        LambdaQueryWrapper<EduCourse> courseWrapper = new LambdaQueryWrapper<>();
        // <if test="name != null && name != ''"></if>
        courseWrapper.like(StringUtils.isNotBlank(title), EduCourse::getTitle, title);
        courseWrapper.eq(StringUtils.isNotBlank(status), EduCourse::getStatus, status);
        courseWrapper.orderByDesc(EduCourse::getGmtCreate);

        courseMapper.selectPage(page, courseWrapper);
        return page;
    }

    /**
     * 根据课程id，删除课程信息
     * @param courseId
     */
    @Transactional
    @Override
    public void removeCourseById(String courseId) {
        // 1 删除小节信息
        videoService.removeVideoByCourseId(courseId);

        // 2 删除章节信息
        chapterService.remove(new LambdaQueryWrapper<EduChapter>().eq(EduChapter::getCourseId, courseId));

        // 3 删除课程简介
        descriptionMapper.deleteById(courseId);

        // 4 删除课程信息
        int delete = courseMapper.deleteById(courseId);
        if (delete <= 0) {
            throw new GuliException(20001, "删除课程失败！");
        }
    }
    /**
     * 查询热门课程
     * @return
     */
    @Cacheable(cacheNames = "eduservice::front", key = "'popularCourse'")
    @Override
    public List<EduCourse> queryPopularCourses() {
        LambdaQueryWrapper<EduCourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(EduCourse::getViewCount);
        Page<EduCourse> page = courseMapper.selectPage(new Page<EduCourse>(1, 8), wrapper);
        if (page != null){
            return page.getRecords();
        }
        return null;
    }

    /**
     * 根据教师id，查询课程列表
     * @param teacherId
     * @return
     */
    @Override
    public List<EduCourse> queryCourseListByTeacherId(String teacherId) {
        LambdaQueryWrapper<EduCourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EduCourse::getTeacherId, teacherId);

        List<EduCourse> courseList = courseMapper.selectList(wrapper);

        return courseList;
    }

    /**
     * 条件查询课程列表带分页
     * @param current
     * @param size
     * @param courseQuery
     * @return
     */
    @Override
    public Map<String, Object> queryFrontCourseListByConditionForPage(Integer current, Integer size, CourseFrontIndexVO courseQuery) {
        // 取出条件对象中的一些属性值
        String subjectParentId = courseQuery.getSubjectParentId();
        String subjectId = courseQuery.getSubjectId();
        String priceSort = courseQuery.getPriceSort();
        String buyCountSort = courseQuery.getBuyCountSort();
        String gmtCreateSort = courseQuery.getGmtCreateSort();

        // 组织sql语句
        LambdaQueryWrapper<EduCourse> wrapper = new LambdaQueryWrapper<>();
        // 根据一级分类查询
        if (StringUtils.isNotBlank(subjectParentId)){
            wrapper.eq(EduCourse::getSubjectParentId, subjectParentId);
        }
        // 根据二级分类查询，但前提得有一级分类id
        if (StringUtils.isNoneBlank(subjectParentId, subjectId)){
            wrapper.eq(EduCourse::getSubjectId, subjectId);
        }
        // 根据价格降序查询
        if (StringUtils.isNotBlank(priceSort)){
            if ("up".equals(priceSort)){
                wrapper.orderByAsc(EduCourse::getPrice);
            }else if ("down".equals(priceSort)){
                wrapper.orderByDesc(EduCourse::getPrice);
            }
        }
        // 根据关注度降序查询
        if (StringUtils.isNotBlank(buyCountSort)){
            wrapper.orderByDesc(EduCourse::getBuyCount);
        }
        // 根据上架时间降序查询
        if (StringUtils.isNotBlank(gmtCreateSort)){
            wrapper.orderByDesc(EduCourse::getGmtModified);
        }

        // 课程需要已经发布
        wrapper.eq(EduCourse::getStatus, "Normal");

        // 创建分页对象
        Page<EduCourse> coursePage = new Page<>(current, size);

        // 查询
        Page<EduCourse> pageParam = courseMapper.selectPage(coursePage, wrapper);

        // 封装返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("items", pageParam.getRecords());
        map.put("current", pageParam.getCurrent());
        map.put("pages", pageParam.getPages());
        map.put("size", pageParam.getSize());
        map.put("total", pageParam.getTotal());
        map.put("hasNext", pageParam.hasNext()); //下一页
        map.put("hasPrevious", pageParam.hasPrevious()); //上一页
        return map;
    }

    /**
     * 根据id，查询课程的详细信息
     * @param id
     * @return
     */
    @Override
    public CourseDetailInfoVO queryCourseDetailInfoById(String id) {
        CourseDetailInfoVO courseInfo = courseMapper.selectCourseDetailInfoById(id);
        return courseInfo;
    }

    /**
     * 为课程订单提供课程信息
     * @param id
     * @return
     */
    @Override
    public CourseInfoVO queryCourseInfoForOrder(String id) {
        CourseDetailInfoVO courseInfoVO = courseMapper.selectCourseDetailInfoById(id);
        if (courseInfoVO != null){
            CourseInfoVO result = new CourseInfoVO();
            result.setId(courseInfoVO.getId())
                    .setCover(courseInfoVO.getCover())
                    .setTitle(courseInfoVO.getTitle())
                    .setTeacherName(courseInfoVO.getTeacherName())
                    .setPrice(courseInfoVO.getPrice());
            return result;
        }
        return null;
    }
}
